/**
 *  rtc.c - Hardware interfaces for rtc driver.
 *
 *  Copyright (C) 2008-2010 ZhangHu
 *  All rights reserved.
 *  E-MAIL: anmnmnly@gmail.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "include/irq.h"
#include "drivers/rtc.h"

#include "hw_rtc.h"
#include "regdef.h"

static rtc_t rtc_record;

static void rtc_isr(void) {
    if(rBCDYEAR == 0x99) {
        rtc_record.year = 0x1999;
    } else {
        rtc_record.year = 0x2000 + rBCDYEAR;
    }

    rtc_record.month = rBCDMON;
    rtc_record.day = rBCDDAY;
    rtc_record.weekday = rBCDDATE;
    rtc_record.hour = rBCDHOUR;
    rtc_record.min = rBCDMIN;
    rtc_record.sec = rBCDSEC;

    rRTCCON = 0x0;
}


void init_rtc(void)
{
    // 2010-6-30 23:59:59
    rtc_record.year = 0x10;
    rtc_record.month = 0x6;
    rtc_record.day = 0x30;
    rtc_record.weekday = WED;
    rtc_record.hour = 0x23;
    rtc_record.min = 0x59;
    rtc_record.sec = 0x59;

    rRTCCON = 0x01; // R/W enable, 1/32768, Normal(merge), No reset

    rBCDYEAR = (uchar_t)rtc_record.year;
    rBCDMON = (uchar_t)rtc_record.month;
    rBCDDAY = (uchar_t)rtc_record.day;
    rBCDDATE = (uchar_t)rtc_record.weekday;
    rBCDHOUR = (uchar_t)rtc_record.hour;
    rBCDMIN = (uchar_t)rtc_record.min;
    rBCDSEC = (uchar_t)rtc_record.sec;

    isrInstall(RTC_ISR_NUM, 0, rtc_isr);
    rINTMSK &= 0x03EFFFFF;    // Enable tick interrupt
    rRTCCON = 0x0;
    rTICINT = 127 + (1 << 7); // START
}



void write_rtc(const rtc_t *value)
{
    if(value == NULL) {
        return;
    }

    rRTCCON = 0x01; // enable write.

    if(value->year != -1) {
        rBCDYEAR = (uchar_t)value->year;
    }

    if(value->month != -1) {
        rBCDMON = (uchar_t)value->month;
    }
    if(value->day != -1) {
        rBCDDAY = (uchar_t)value->day;
    }
    if(value->weekday != -1) {
        rBCDDATE = (uchar_t)value->weekday;
    }
    if(value->hour != -1) {
        rBCDHOUR = (uchar_t)value->hour;
    }
    if(value->min != -1) {
        rBCDMIN = (uchar_t)value->min;
    }
    if(value->sec != -1) {
        rBCDSEC = (uchar_t)value->sec;
    }

    rRTCCON = 0x00;
}



void read_rtc(rtc_t *value)
{
    if(value == NULL) {
        return;
    }

    value->year = rtc_record.year;
    value->month = rtc_record.month;
    value->day = rtc_record.day;
    value->weekday = rtc_record.weekday;
    value->hour = rtc_record.hour;
    value->min = rtc_record.min;
    value->sec = rtc_record.sec;
}

